<template>
  <div class="container">
    <h3 class="h3">使用draw绘制正方形、矩形、六芒星</h3>
    <h4>
      <el-select
        id="type"
        v-model="tool"
        class="select"
      >
        <el-option
          v-for="item in tools"
          :key="item.value"
          :value="item.value"
        >{{ item.label }}</el-option>
      </el-select>
    </h4>

    <div id="vue-openlayers" />
  </div>
</template>

<script>
import 'ol/ol.css'
import { Map, View } from 'ol'
import Tile from 'ol/layer/Tile'
// import OSM from 'ol/source/OSM'
import { XYZ } from 'ol/source'
import LayerVector from 'ol/layer/Vector'
import SourceVector from 'ol/source/Vector'
import Draw, {
  createRegularPolygon,
  createBox
} from 'ol/interaction/Draw'
import Polygon from 'ol/geom/Polygon'
import Fill from 'ol/style/Fill'
import Stroke from 'ol/style/Stroke'
import Style from 'ol/style/Style'
import Circle from 'ol/style/Circle'

export default {
  data() {
    return {
      tool: 'Square',
      tools: [
        {
          value: 'Square',
          label: '正方形'
        },
        {
          value: 'Rectangle',
          label: '矩形'
        },
        {
          value: 'Hexagram',
          label: '六芒星'
        }
      ],
      map: null, // 地图
      draw: null,
      source: new SourceVector({
        wrapX: false
      })
    }
  },
  watch: {
    tool(newVal) {
      this.addInteraction()
    }
  },
  mounted() {
    this.initMap()
  },
  methods: {
    initMap() {
      const raster = new Tile({
        source: new XYZ({
          url: 'http://{a-c}.tile.openstreetmap.de/{z}/{x}/{y}.png'
        })
      })

      const vector = new LayerVector({
        source: this.source,
        // Vector层显示的样式
        style: new Style({
          fill: new Fill({
            color: '#00f'
          }),
          stroke: new Stroke({
            width: 2,
            color: '#ff0'
          }),
          image: new Circle({ // 点样式
            radius: 5,
            fill: new Fill({
			  color: '#ff0000'
            })
	     })
        })
      })
      this.map = new Map({
        target: 'vue-openlayers',
        layers: [raster, vector],
        view: new View({
          projection: 'EPSG:4326',
          center: [113.1206, 23.034996],
          zoom: 10
        })
      })
      this.addInteraction()
    },
    addInteraction() {
      if (this.draw !== null) {
        this.map.removeInteraction(this.draw)
      }
      if (this.tool !== 'None') {
        let geometryFunction
        const type = 'Circle'

        if (this.tool === 'Square') {
          // 方形
          geometryFunction = createRegularPolygon(4)
        } else if (this.tool === 'Rectangle') {
          // 矩形
          geometryFunction = createBox()
        } else if (this.tool === 'Hexagram') {
          geometryFunction = function(coordinates, geometry) {
            // 中心点
            const center = coordinates[0]
            // 鼠标点击的另一个点
            const last = coordinates[1]
            const dx = center[0] - last[0]
            const dy = center[1] - last[1]
            // 半径
            const radius = Math.sqrt(dx * dx + dy * dy)
            // 旋转的角度
            const rotation = Math.atan2(dy, dx)
            // 用来记录顶点坐标的数组
            const newCoordinates = []
            // 顶点个数
            const numPoints = 12
            for (let i = 0; i < numPoints; ++i) {
              // 顶点相对转过的角度
              const angle = rotation + i * 2 * Math.PI / numPoints
              // 确定凸顶点和凹顶点
              const fraction = i % 2 === 0 ? 1 : 0.58
              // 计算顶点的坐标
              const offsetX = radius * fraction * Math.cos(angle)
              const offsetY = radius * fraction * Math.sin(angle)
              newCoordinates.push([center[0] + offsetX, center[1] + offsetY])
            }
            newCoordinates.push(newCoordinates[0].slice())
            if (!geometry) {
              geometry = new Polygon([newCoordinates])
            } else {
              geometry.setCoordinates([newCoordinates])
            }
            return geometry
          }
        }

        this.draw = new Draw({
          source: this.source,
          type,
          geometryFunction
        })
        this.map.addInteraction(this.draw)
      }
    }
  }
}
</script>
<style scoped>
.container {
  width: 1240px;
  height: 690px;
  margin: 50px auto;
  border: 1px solid #42b983;
}
#vue-openlayers {
  width: 1200px;
  height: 550px;
  margin: 0 auto;
  margin-top: 10px;
  border: 1px solid #42b983;
  position: relative;
}
.h3 {
  text-align: center;
}
.select{
  margin-left: 500px;
}
</style>
